package android.slc.box.core.ui;

import android.slc.box.core.launcher.WindowLauncher;
import android.slc.box.core.launcher.WindowLauncherBridge;
import android.slc.box.core.utils.WindowUtils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import de.saxsys.mvvmfx.FxmlView;
import de.saxsys.mvvmfx.InjectViewModel;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Window;

import java.lang.ref.WeakReference;
import java.util.Objects;

/**
 * @author slc
 * @date 2022/03/21 下午 1:41
 */
public abstract class BaseView<VM extends BaseViewModel, WL extends WindowLauncher<VT>, VT extends Window> implements FxmlView<VM>,
        ViewLife,
        WindowLauncherBridge<WL, VT> {
    protected final static Log LOG = LogFactory.get();

    @InjectViewModel
    private VM appVm;


    /**
     * 视图生命周期包装
     */
    private WeakReference<ViewLifeHandle> viewLifeHandleReference;

    /**
     * 窗口启动器
     */
    private WL windowLauncher;

    /**
     * 盒子内容试图
     */
    @FXML
    private Pane boxContentPane;

    protected VM getViewModel() {
        return appVm;
    }

    /**
     * 此方法由mvvmFx框架调用
     * 初始化
     */
    public final void initialize() {
        if (this.getBoxContentPane() == null) {
            throw new RuntimeException("没有找到boxContentParent，请在视图对应的XML文件根节点进行配置！");
        }
        //先初始化ViewLifeHandle后续的初始化操作需要此对象
        this.viewLifeHandleReference = new WeakReference<>(setViewLifeHandle());
        //初始化WindowLauncher
        initWindowLauncher();
        this.getViewLifeHandle().initViewLife(getViewModel(), this, this.bindViewLaterRunLast());
    }

    //ViewLifeWrap start
    @Override
    public void onCreate() {
        LOG.info("View.onCreate");
    }

    @Override
    public void onViewAdded() {
        LOG.info("View.onViewAdded");
    }

    @Override
    public void onBindViewBefore() {

    }

    private void initWindowLauncher() {
        this.windowLauncher = setWindowLauncher();
        //addOnWindowsCloseListener(getViewLifeHandle());
    }

    @Override
    public void onBindView() {

    }

    @Override
    public void onBindViewLater() {
        WindowUtils.setGlobalTitleBarHeight(requireWindow());
    }

    @Override
    public boolean bindViewLaterRunLast() {
        return true;
    }

    @Override
    public void onRegisterLiveEvent() {
        onRegisterLiveEvent(getViewModel());
    }

    protected void onRegisterLiveEvent(VM vm) {

    }

    @Override
    public void onViewRemoved() {
        LOG.info("View.onViewRemoved");
    }

    @Override
    public void onDestroy() {
        //removeOnWindowsCloseListener(getViewLifeHandle());
        getViewModel().clear();
        getWindowLauncher().destroyLauncher();
        this.appVm = null;
        LOG.info("View.onDestroy");
    }

    @Override
    public final void finish() {
        ViewLife.finishWindow(requireWindow());
    }

    @Override
    public void finishView() {
        Pane boxContentPaneParent = (Pane) getBoxContentPane().getParent();
        if (Objects.equals(getBoxContentPane(), getScreenRootPane()) || boxContentPaneParent == null) {
            finish();
            return;
        }
        if (Objects.equals(boxContentPaneParent, getScreenRootPane()) && CollectionUtil.size(boxContentPaneParent.getChildren()) == 1) {
            finish();
            return;
        }
        boxContentPaneParent.getChildren().remove(getBoxContentPane());
    }

    //ViewLifeWrap end
    protected ViewLifeHandle setViewLifeHandle() {
        ViewLifeHandle viewLifeHandle = new ViewLifeViewLifeHandleImpl();
        return viewLifeHandle;
    }

    /**
     * 获取视图生命周期包装
     *
     * @return
     */
    protected ViewLifeHandle getViewLifeHandle() {
        return viewLifeHandleReference.get();
    }

    protected abstract WL setWindowLauncher();

    /**
     * 获取获取StageScope
     *
     * @return
     */
    public WL getWindowLauncher() {
        return this.windowLauncher;
    }

    protected Pane getBoxContentPane() {
        return boxContentPane;
    }

    protected Pane getScreenRootPane() {
        Scene scene = getBoxContentPane().getScene();
        if (scene == null) {
            return null;
        }
        return (Pane) scene.getRoot();
    }

    //操作区
    protected void applyBoxContentPane2WindowSize() {
        boxContentPane.prefWidth(requireWindow().getScene().getWidth());
        boxContentPane.prefHeight(requireWindow().getScene().getHeight());
        boxContentPane.maxWidth(requireWindow().getScene().getWidth());
        boxContentPane.maxHeight(requireWindow().getScene().getHeight());

        boxContentPane.prefWidthProperty().bind(requireWindow().getScene().widthProperty());
        boxContentPane.prefHeightProperty().bind(requireWindow().getScene().heightProperty());
        boxContentPane.maxWidthProperty().bind(requireWindow().getScene().widthProperty());
        boxContentPane.maxHeightProperty().bind(requireWindow().getScene().heightProperty());
    }
}
